# Copyright (C) 2025 Huawei Technologies Co., Ltd. All rights reserved.	

<# NOTE: openUBMC Setting module Cmdlets #>

function Reset-openUBMC {
<#
.SYNOPSIS
Reset openUBMC.

.DESCRIPTION
Reset openUBMC.

.PARAMETER Session
openUBMC redfish session object which is created by Connect-openUBMC cmdlet.
A session object identifies an openUBMC server to which this cmdlet will be executed.

.OUTPUTS
None
Returns None if cmdlet executes successfully.
In case of an error or warning, exception will be returned.

.EXAMPLE

PS C:\> $credential = Get-Credential
PS C:\> $session = Connect-openUBMC -Address 192.168.1.1 -Credential $credential -TrustCert
PS C:\> Reset-openUBMC $session


.LINK
https://gitcode.com/openUBMC/cmdlets_plugin

Connect-openUBMC
Disconnect-openUBMC

#>
  [CmdletBinding()]
  param (
    [RedfishSession[]]
    [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
    $Session
  )

  begin {
  }

  process {
    Assert-ArrayNotNull $Session 'Session'

    $Logger.info("Invoke Reset openUBMC function")

    $ScriptBlock = {
      param($RedfishSession, $Payload)
      $(Get-Logger).info($(Trace-Session $RedfishSession "Invoke Reset openUBMC now"))
      $Path = "/Managers/$($RedfishSession.Id)/Actions/Manager.Reset"
      $Logger.info($(Trace-Session $RedfishSession "Sending payload: $($Payload | ConvertTo-Json)"))
      Invoke-RedfishRequest $RedfishSession $Path 'POST' $Payload | Out-Null
      return $null
    }

    try {
      $tasks = New-Object System.Collections.ArrayList
      $pool = New-RunspacePool $Session.Count
      for ($idx = 0; $idx -lt $Session.Count; $idx++) {
        $RedfishSession = $Session[$idx]
        $Payload = @{"ResetType" = "ForceRestart"; }
        $Parameters = @($RedfishSession, $Payload)
        $Logger.info($(Trace-Session $RedfishSession "Submit Reset openUBMC task"))
        [Void] $tasks.Add($(Start-ScriptBlockThread $pool $ScriptBlock $Parameters))
      }

      $Results = Get-AsyncTaskResults $tasks
      return ,$Results
    }
    finally {
      Close-Pool $pool
    }
  }

  end {
  }
}


function Restore-openUBMCFactorySetting {
<#
.SYNOPSIS
Restore the factory settings.

.DESCRIPTION
Restore the factory settings.
Note: This cmdlet is a high-risk operation. It should be used with caution.

.PARAMETER Session
openUBMC redfish session object which is created by Connect-openUBMC cmdlet.
A session object identifies an openUBMC server to which this cmdlet will be executed.

.OUTPUTS
None
Returns None if cmdlet executes successfully.
In case of an error or warning, exception will be returned.

.EXAMPLE

Restore factory settings

PS C:\> $credential = Get-Credential
PS C:\> $session = Connect-openUBMC -Address 192.168.1.1 -Credential $credential -TrustCert
PS C:\> Restore-openUBMCFactorySetting $session


.LINK
https://gitcode.com/openUBMC/cmdlets_plugin

Export-openUBMCBIOSSetting
Import-openUBMCBIOSSetting
Reset-openUBMCBIOSSetting
Connect-openUBMC
Disconnect-openUBMC

#>
  [CmdletBinding()]
  param (
    [RedfishSession[]]
    [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
    $Session
  )

  begin {
  }

  process {
    Assert-ArrayNotNull $Session 'Session'

    $Logger.info("Invoke Restore BIOS Factory function")

    $ScriptBlock = {
      param($RedfishSession)
      $Path = "/Managers/$($RedfishSession.Id)/Actions/Oem/openUBMC/Manager.RestoreFactory"
      Invoke-RedfishRequest $RedfishSession $Path 'Post' | Out-Null
      return $null
    }

    try {
      $tasks = New-Object System.Collections.ArrayList
      $pool = New-RunspacePool $Session.Count
      for ($idx = 0; $idx -lt $Session.Count; $idx++) {
        $RedfishSession = $Session[$idx]
        $Logger.info($(Trace-Session $RedfishSession "Submit Restore BIOS Factory task"))
        [Void] $tasks.Add($(Start-ScriptBlockThread $pool $ScriptBlock @($RedfishSession)))
      }

      $Results = Get-AsyncTaskResults $tasks
      return ,$Results
    }
    finally {
      Close-Pool $pool
    }
  }

  end {
  }
}

function Get-openUBMCIP {
<#
.SYNOPSIS
Querying an openUBMC Network Port Resource.

.DESCRIPTION
Querying an openUBMC Network Port Resource.

.PARAMETER Session
openUBMC redfish session object which is created by Connect-openUBMC cmdlet.
A session object identifies an openUBMC server to which this cmdlet will be executed.

.OUTPUTS
PSObject[]
Returns PSObject which contains all support services infomation if cmdlet executes successfully.
In case of an error or warning, exception will be returned.

.EXAMPLE

PS C:\> $Credential = Get-Credential
PS C:\> $Session = Connect-openUBMC -Address 192.168.1.1 -Credential $Credential -TrustCert
PS C:\> $openUBMCIP = Get-openUBMCIP -Session $Session
PS C:\> $openUBMCIP

Host                  : 192.168.1.1
Id                    : 04338932ede2
Name                  : Manager Ethernet Interface
PermanentMACAddress   : xx:xx:xx:xx:xx:xx
HostName              : server2
FQDN                  : server2.plugin.com
VLAN                  : @{VLANEnable=False; VLANId=0}
IPv4Addresses         : {@{Address=192.168.1.1; SubnetMask=255.255.0.0; Gateway=10.1.0.1; AddressOrigin=Static}}
IPv6Addresses         : {@{Address=fc00:10::2; PrefixLength=64; AddressOrigin=Static}, @{Address=fe80::633:89ff:fe32:ede2; PrefixLength=64; AddressOrigin=LinkLocal}}
IPv6StaticAddresses   : {@{Address=fc00:10::2; PrefixLength=64}}
IPv6DefaultGateway    : fc00:10::1
NameServers           : {192.168.1.10, }
IPVersion             : IPv4AndIPv6
NetworkPortMode       : Fixed
ManagementNetworkPort : @{Type=Dedicated; PortNumber=1}

This example shows how to query the IP of a server

.EXAMPLE

PS C:\> $Credential = Get-Credential
PS C:\> $Session = Connect-openUBMC -Address 192.168.1.1-3 -Credential $Credential -TrustCert
PS C:\> $openUBMCIP = Get-openUBMCIP -Session $Session
PS C:\> $openUBMCIP

Host                  : 192.168.1.1
Id                    : 04338932ede2
Name                  : Manager Ethernet Interface
PermanentMACAddress   : xx:xx:xx:xx:xx:xx
HostName              : server2
FQDN                  : server2.plugin.com
VLAN                  : @{VLANEnable=False; VLANId=0}
IPv4Addresses         : {@{Address=192.168.1.1; SubnetMask=255.255.0.0; Gateway=10.1.0.1; AddressOrigin=Static}}
IPv6Addresses         : {@{Address=fc00:10::2; PrefixLength=64; AddressOrigin=Static}, @{Address=fe80::633:89ff:fe32:ede2; PrefixLength=64; AddressOrigin=LinkLocal}}
IPv6StaticAddresses   : {@{Address=fc00:10::2; PrefixLength=64}}
IPv6DefaultGateway    : fc00:10::1
NameServers           : {192.168.1.10, }
IPVersion             : IPv4AndIPv6
NetworkPortMode       : Fixed
ManagementNetworkPort : @{Type=Dedicated; PortNumber=1}

Host                  : 192.168.1.3
Id                    : 04885fd4c9d6
Name                  : Manager Ethernet Interface
PermanentMACAddress   : xx:xx:xx:xx:xx:xx
HostName              : server3
FQDN                  : server3.plugin.com
VLAN                  : @{VLANEnable=False; VLANId=0}
IPv4Addresses         : {@{Address=192.168.1.3; SubnetMask=255.255.0.0; Gateway=10.1.0.1; AddressOrigin=Static}}
IPv6Addresses         : {@{Address=fc00:10::3; PrefixLength=64; AddressOrigin=Static}, @{Address=fe80::633:89ff:fe32:ede3; PrefixLength=64; AddressOrigin=LinkLocal}}
IPv6StaticAddresses   : {@{Address=fc00:10::3; PrefixLength=64}}
IPv6DefaultGateway    : fc00:10::1
NameServers           : {192.168.1.10, }
IPVersion             : IPv4AndIPv6
NetworkPortMode       : Fixed
ManagementNetworkPort : @{Type=Dedicated; PortNumber=1}

This example shows how to query the IP of multiple server

.LINK
https://gitcode.com/openUBMC/cmdlets_plugin

Set-openUBMCIP
Connect-openUBMC
Disconnect-openUBMC

#>
  [CmdletBinding()]
  param (
    [RedfishSession[]]
    [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
    $Session
  )

  begin {
  }

  process {
    Assert-ArrayNotNull $Session 'Session'

    $Logger.info("Invoke Get BMC IP function")

    $ScriptBlock = {
      param($RedfishSession)
      $(Get-Logger).info($(Trace-Session $RedfishSession "Invoke get BMC IP now"))
      $EthernetInterfaces_ID = Get-EthernetInterfaces-ID $RedfishSession
      $Path = "/Managers/$($RedfishSession.Id)/EthernetInterfaces/$EthernetInterfaces_ID"
      $Response = Invoke-RedfishRequest $RedfishSession $Path | ConvertFrom-WebResponse
      
      $Properties = @(
        "^Id$",
        "^Name$",
        "^PermanentMACAddress$",
        "^HostName$",
        "^FQDN$",
        "^VLAN$",
        "^IPv4Addresses$",
        "^IPv6Addresses$",
        "^IPv6StaticAddresses$",
        "^IPv6DefaultGateway$",
        "^NameServers$"
        )
      $openUBMCIP = Copy-ObjectProperties $Response $Properties
      $openUBMCIP | Add-Member -MemberType NoteProperty "IPVersion" $Response.Oem.openUBMC.IPVersion
      $openUBMCIP | Add-Member -MemberType NoteProperty "NetworkPortMode" $Response.Oem.openUBMC.NetworkPortMode
      $openUBMCIP | Add-Member -MemberType NoteProperty "ManagementNetworkPort" $Response.Oem.openUBMC.ManagementNetworkPort
      return $(Update-SessionAddress $RedfishSession $openUBMCIP)
    }

    try {
      $tasks = New-Object System.Collections.ArrayList
      $pool = New-RunspacePool $Session.Count
      for ($idx = 0; $idx -lt $Session.Count; $idx++) {
        $RedfishSession = $Session[$idx]
        $Logger.info($(Trace-Session $RedfishSession "Submit get BMC IP task"))
        [Void] $tasks.Add($(Start-ScriptBlockThread $pool $ScriptBlock @($RedfishSession)))
      }

      $Results = Get-AsyncTaskResults $tasks
      return ,$Results
    }
    finally {
      Close-Pool $pool
    }
  }

  end {
  }
}

function Set-openUBMCIP {
<#
.SYNOPSIS
Modify openUBMC network port information.

.DESCRIPTION
Modify openUBMC network port information.

.PARAMETER Session
openUBMC redfish session object which is created by Connect-openUBMC cmdlet.
A session object identifies an openUBMC server to which this cmdlet will be executed.

.PARAMETER IPVersion
Whether IPv4/IPv6 is enabled.
Available Value Set: ('IPv4', 'IPv6', 'IPv4AndIPv6')

.PARAMETER IPv4Address
Indicates the IPv4 address.

.PARAMETER IPv4SubnetMask
Indicates the subnet mask of the IPv4 address.

.PARAMETER IPv4Gateway
Indicates the gateway IP address.

.PARAMETER IPv4AddressOrigin
How the IPv4 address is allocated.
Available Value Set: ('Static', 'DHCP')

.PARAMETER IPv6Address
Indicates the IPv6 address.

.PARAMETER IPv6PrefixLength
Prefix length of the IPv6 address.
Available Value range: [0, 128]

.PARAMETER IPv6AddressOrigin
Specifies how IPv6 addresses are allocated.
Available Value Set: ('Static', 'DHCPv6')

.PARAMETER IPv6Gateway
IPv6 gateway address of the openUBMC network port.

.OUTPUTS
Null
Returns Null if cmdlet executes successfully.
In case of an error or warning, exception will be returned.

.EXAMPLE

PS C:\> $Credential = Get-Credential
PS C:\> $Session = Connect-openUBMC -Address 192.168.1.1 -Credential $Credential -TrustCert
PS C:\> Set-openUBMCIP -Session $Session -IPVersion IPv4AndIPv6 `
          -IPv4Address 192.168.1.1 -IPv4SubnetMask 255.255.0.0 -IPv4Gateway 10.1.0.1 -IPv4AddressOrigin Static `
          -IPv6Address fc00:10:2 -IPv6PrefixLength 64 -IPv6Gateway fc00:10:1 -IPv6AddressOrigin Static

This example shows how to modify the IP of a server

.EXAMPLE

PS C:\> $Credential = Get-Credential
PS C:\> $Session = Connect-openUBMC -Address 192.168.1.1,192.168.1.3 -Credential $Credential -TrustCert
PS C:\> $IPVersion = @("IPv4AndIPv6", "IPv4")
PS C:\> $IPv4Address = @("192.168.1.12", "192.168.1.13")
PS C:\> $IPv6Address = @("fc00:10::12", "fc00:10:13")
PS C:\> Set-openUBMCIP -Session $Session -IPVersion $IPVersion `
          -IPv4Address $IPv4Address -IPv4SubnetMask 255.255.0.0 -IPv4Gateway 10.1.0.1 -IPv4AddressOrigin Static `
          -IPv6Address $IPv6Address -IPv6PrefixLength 64 -IPv6Gateway fc00:10:1 -IPv6AddressOrigin Static

This example shows how to modify the IP of multiple servers

.LINK
https://gitcode.com/openUBMC/cmdlets_plugin

Get-openUBMCIP
Connect-openUBMC
Disconnect-openUBMC

#>
  [CmdletBinding()]
  param (
    [RedfishSession[]]
    [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
    $Session,

    [IPVersion[]]
    [parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
    $IPVersion,

    [string[]]
    [parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
    $IPv4Address,

    [string[]]
    [parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
    $IPv4SubnetMask,

    [string[]]
    [parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
    $IPv4Gateway,

    [IPv4AddressOrigin[]]
    [parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
    $IPv4AddressOrigin,

    [string[]]
    [parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
    $IPv6Address,

    [int32[]]
    [parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
    [ValidateRange(0, 128)]
    $IPv6PrefixLength,

    [string[]]
    [parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
    $IPv6Gateway,

    [IPv6AddressOrigin[]]
    [parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
    $IPv6AddressOrigin
  
  )

  begin {
  }

  process {
    Assert-ArrayNotNull $Session 'Session'
    $IPVersionList = Get-OptionalMatchedSizeArray $Session $IPVersion
    $IPv4AddressList = Get-OptionalMatchedSizeArray $Session $IPv4Address
    $IPv4GatewayList = Get-OptionalMatchedSizeArray $Session $IPv4Gateway
    $IPv4SubnetMaskList = Get-OptionalMatchedSizeArray $Session $IPv4SubnetMask
    $IPv4AddressOriginList = Get-OptionalMatchedSizeArray $Session $IPv4AddressOrigin
    $IPv6AddresseList = Get-OptionalMatchedSizeArray $Session $IPv6Address
    $IPv6PrefixLengthList = Get-OptionalMatchedSizeArray $Session $IPv6PrefixLength
    $IPv6AddressOriginList = Get-OptionalMatchedSizeArray $Session $IPv6AddressOrigin
    $IPv6GatewayList = Get-OptionalMatchedSizeArray $Session $IPv6Gateway

    $Logger.info("Invoke Set BMC IP function")

    $ScriptBlock = {
      param($RedfishSession, $Payload)
      $(Get-Logger).info($(Trace-Session $RedfishSession "Invoke Set BMC IP now"))
      $EthernetInterfaces_ID = Get-EthernetInterfaces-ID $RedfishSession
      $Path = "/Managers/$($RedfishSession.Id)/EthernetInterfaces/$EthernetInterfaces_ID"
      
      $IPv4AddrDict = @{
        "Address" = $Payload.IPv4Address;
        "SubnetMask" = $Payload.IPv4SubnetMask;
        "Gateway" = $Payload.IPv4Gateway;
        "AddressOrigin" = $Payload.IPv4AddressOrigin
      }| Remove-EmptyValues
      $IPv4AddrList = New-Object System.Collections.ArrayList
      if ($IPv4AddrDict.Count -gt 0) {
        [Void] $IPv4AddrList.Add($IPv4AddrDict)
      } 

      $IPv6AddrDict = @{
        "Address" = $Payload.IPv6Address;
        "PrefixLength" = $Payload.IPv6PrefixLength;
        "AddressOrigin" = $Payload.IPv6AddressOrigin
      }| Remove-EmptyValues
      $IPv6AddrList = New-Object System.Collections.ArrayList
      if ($IPv6AddrDict.Count -gt 0) {
        [Void] $IPv6AddrList.Add($IPv6AddrDict)
      } 
      
      $CompletePlayload = @{}

      if ($Payload.IPVersion) {
        $Oem = @{
          "openUBMC" = @{
            "IPVersion" = $Payload.IPVersion
          }
        }
        $CompletePlayload.Oem = $Oem 
      }

      if ($Payload.IPv6Gateway) {
        $CompletePlayload.IPv6DefaultGateway = $Payload.IPv6Gateway
      }

      if ($IPv4AddrList.Count -gt 0) {
        $CompletePlayload.IPv4Addresses = $IPv4AddrList
      }

      if ($IPv6AddrList.Count -gt 0) {
        $CompletePlayload.IPv6Addresses = $IPv6AddrList
      }

      $Logger.info($(Trace-Session $RedfishSession "Sending payload: $($CompletePlayload | ConvertTo-Json -Depth 5)"))
      $Response = Invoke-RedfishRequest $RedfishSession $Path 'Patch' $CompletePlayload
      Resolve-RedfishPartialSuccessResponse $RedfishSession $Response | Out-Null
      return $null
    }

    try {
      $tasks = New-Object System.Collections.ArrayList
      $pool = New-RunspacePool $Session.Count
      for ($idx = 0; $idx -lt $Session.Count; $idx++) {
        $RedfishSession = $Session[$idx]
        $Payload = @{
          IPVersion = $IPVersionList[$idx];
          IPv4Address = $IPv4AddressList[$idx];
          IPv4Gateway = $IPv4GatewayList[$idx];
          IPv4SubnetMask = $IPv4SubnetMaskList[$idx];
          IPv4AddressOrigin = $IPv4AddressOriginList[$idx];
          IPv6Address = $IPv6AddresseList[$idx];
          IPv6PrefixLength = $IPv6PrefixLengthList[$idx];
          IPv6AddressOrigin = $IPv6AddressOriginList[$idx];
          IPv6Gateway = $IPv6GatewayList[$idx]
        }| Remove-EmptyValues | Resolve-EnumValues

        if (-not (Assert-IPv4 $IPv4Address)) {
          throw $(Get-i18n ERROR_IPV4_ADDRESS_INVALID)
        }

        if (-not (Assert-IPv4 $IPv4Gateway)) {
          throw $(Get-i18n ERROR_IPV4_GATEWAY_INVALID)
        }

        if (-not (Assert-IPv4 $IPv4SubnetMask)) {
          throw $(Get-i18n ERROR_IPV4_SUBNETMASK_INVALID)
        }

        if (-not (Assert-IPv6 $IPv6Address)) {
          throw $(Get-i18n ERROR_IPV6_ADDRESS_INVALID)
        }

        if (-not (Assert-IPv6 $IPv6Gateway)) {
          throw $(Get-i18n ERROR_IPV6_GATEWAY_INVALID)
        }

        if ($Payload.Count -eq 0) {
          throw $(Get-i18n ERROR_NO_UPDATE_PAYLOAD)
        }

        $Parameters = @($RedfishSession, $Payload)
        $Logger.info($(Trace-Session $RedfishSession "Submit Set BMC IP task"))
        [Void] $tasks.Add($(Start-ScriptBlockThread $pool $ScriptBlock $Parameters))
      }

      $Results = Get-AsyncTaskResults $tasks
      return ,$Results
    }
    finally {
      Close-Pool $pool
    }
  }

  end {
  }
}